﻿using Data;
using Data.Tables;
using PayrollExpress.Helpers;
using PayrollExpress.Models;
using System;
using System.Data.Entity;
using System.Web.Mvc;
using System.Linq;

namespace PayrollExpress.Controllers
{
    public class MasterfileController : BaseController
    {

        public ActionResult Index()
        {
            try
            {
                return RedirectToAction("Index", "Home");
            }
            catch (Exception ex)
            {
                return Error(ex);
            }
        }

        #region Holidays

        public ActionResult Holidays(int? year)
        {
            try
            {
                CheckUserPageAccess(BaseHelper.Page.Holidays);

                var dataList = MasterfileHelper.GetHolidayListModel(year);
                return View(dataList);
            }
            catch (Exception ex)
            {
                return Error(ex);
            }
        }

        public ActionResult HolidaysAdd(int? year)
        {
            try
            {
                CheckUserPageAccess(BaseHelper.Page.Holidays);

                var model = new HolidaysAddModel();

                using (var db = new DatabaseContext())
                {
                    model = MasterfileHelper.GetHolidaysAddModel(db, year);
                }

                return View(BaseHelper.PageAddEditSave.HolidaysAdd.ToString(), model);
            }
            catch (Exception ex)
            {
                return Error(ex);
            }
        }

        public ActionResult HolidaysSave(HolidaysAddModel model, string command)
        {
            try
            {
                using (var db = new DatabaseContext())
                {
                    if (command == BaseHelper.PageAction.Add.ToString())
                    {
                        foreach (var item in model.NewRecurringHolidays)
                        {

                            if (item.Month > 0
                                && item.Day > 0
                                && item.Year > 0
                                && !string.IsNullOrEmpty(item.Description)
                                && item.HolidayTypeID > 0)
                            {
                                var newRecurringHoliday = new Holiday();

                                newRecurringHoliday.Month = item.Month;
                                newRecurringHoliday.Day = item.Day;
                                newRecurringHoliday.Year = item.Year;
                                newRecurringHoliday.Description = item.Description;
                                newRecurringHoliday.HolidayTypeID = item.HolidayTypeID;
                                newRecurringHoliday.RecurringHolidayID = item.RecurringHolidayID;

                                db.Holidays.Add(newRecurringHoliday);
                            }
                        }

                        foreach (var item in model.NewHolidays)
                        {
                            if (item.Month > 0
                                && item.Day > 0
                                && item.Year > 0
                                && !string.IsNullOrEmpty(item.Description)
                                && item.HolidayTypeID > 0)
                            {
                                var newHoliday = new Holiday();
                                newHoliday.Month = item.Month;
                                newHoliday.Day = item.Day;
                                newHoliday.Year = item.Year;
                                newHoliday.Description = item.Description;
                                newHoliday.HolidayTypeID = item.HolidayTypeID;
                                newHoliday.RecurringHolidayID = item.RecurringHolidayID;

                                db.Holidays.Add(newHoliday);
                            }
                        }

                        db.SaveChanges();
                    }
                    else
                    {
                        // cancelled
                    }
                }

                return RedirectToAction(BaseHelper.Page.Holidays.ToString());
            }
            catch (Exception ex)
            {
                return Error(ex);
            }
        }

        public ActionResult HolidayEdit(int? id)
        {
            try
            {
                CheckUserPageAccess(BaseHelper.Page.Holidays);

                var model = new HolidayEditModel();

                using (var db = new DatabaseContext())
                {
                    model = MasterfileHelper.GetHolidayEditModel(db, id);
                }

                return View(BaseHelper.PageAddEditSave.HolidayEdit.ToString(), model);
            }
            catch (Exception ex)
            {
                return Error(ex);
            }
        }

        

        public ActionResult HolidaySave(HolidayEditModel model, string command)
        {
            try
            {
                using (var db = new DatabaseContext())
                {
                    if (command == BaseHelper.PageAction.Edit.ToString())
                    {
                        db.Entry(model.Type).State = EntityState.Modified;
                        db.SaveChanges();
                    }
                    else
                    {
                        // cancelled
                    }
                }

                return RedirectToAction(BaseHelper.Page.Holidays.ToString());
            }
            catch (Exception ex)
            {
                return Error(ex);
            }
        }

        public ActionResult GetDays(int month, int year)
        {
            try
            {
                CheckUserPageAccess(BaseHelper.Page.Holidays);

                var db = new DatabaseContext();
                var days = AdministrationHelper.CalendarDayDropDownList(month, year);

                return Json(days, JsonRequestBehavior.AllowGet);
            }
            catch (Exception ex)
            {
                return View("Error", ex);
            }
        }

        #endregion

        #region Employees

        public ActionResult Employees(int? workLocationID)
        {
            try
            {
                CheckUserPageAccess(BaseHelper.Page.Employees);

                var dataList = new EmployeeListModel();
                using (var db = new DatabaseContext())
                {
                    dataList = MasterfileHelper.GetEmployeeListModel(db, User.Identity.Name, workLocationID);
                }
                
                return View(dataList);
            }
            catch (Exception ex)
            {
                return Error(ex);
            }
        }

        [HttpPost]
        public ActionResult EmployeesRefresh(EmployeeListModel model)
        {
            try
            {
                CheckUserPageAccess(BaseHelper.Page.Employees);

                return RedirectToAction(BaseHelper.Page.Employees.ToString(), new { workLocationID = model.SelectedWorkLocationID });
            }
            catch (Exception ex)
            {
                return Error(ex);
            }
        }

        public ActionResult EmployeeAddEdit(int? workLocationID, string employeeCode)
        {
            try
            {
                CheckUserPageAccess(BaseHelper.Page.Employees);

                var model = new EmployeeAddEditModel();
                using (var db = new DatabaseContext())
                {
                    model = MasterfileHelper.GetEmployeeAddEditModel(db, workLocationID.GetValueOrDefault(), employeeCode);
                }

                return View(BaseHelper.PageAddEditSave.EmployeeAddEdit.ToString(), model);
            }
            catch (Exception ex)
            {
                return Error(ex);
            }
        }

        public ActionResult EmployeeSave(EmployeeAddEditModel model, string command)
        {
            try
            {
                using (var db = new DatabaseContext())
                {
                    if (command == BaseHelper.PageAction.Add.ToString())
                    {
                        db.Employees.Add(model.Type);
                        db.SaveChanges();
                    }
                    else if (command == BaseHelper.PageAction.Edit.ToString())
                    {
                        db.Entry(model.Type).State = System.Data.Entity.EntityState.Modified;
                        db.SaveChanges();
                    }
                    else
                    {
                        // cancelled
                    }
                }

                return RedirectToAction(BaseHelper.Page.Employees.ToString(),
                    new { workLocationID = model.Type.WorkLocationID });
            }
            catch (Exception ex)
            {
                return Error(ex);
            }
        }

        #endregion

        #region Employee Contracts

        public ActionResult EmployeeContracts(string employeeCode)
        {
            try
            {
                CheckUserPageAccess(BaseHelper.Page.Employees);

                var dataList = MasterfileHelper.GetEmployeeContractListModel(employeeCode);
                return View(dataList);
            }
            catch (Exception ex)
            {
                return Error(ex);
            }
        }

        public ActionResult EmployeeContractAddEdit(string employeeCode, int? id)
        {
            try
            {
                CheckUserPageAccess(BaseHelper.Page.Employees);

                var model = new EmployeeContractAddEditModel();

                using (var db = new DatabaseContext())
                {
                    model = MasterfileHelper.GetEmployeeContractAddEditModel(db, employeeCode, id);
                }

                return View(BaseHelper.PageAddEditSave.EmployeeContractAddEdit.ToString(), model);
            }
            catch (Exception ex)
            {
                return Error(ex);
            }
        }

        public ActionResult EmployeeContractSave(EmployeeContractAddEditModel model, string command)
        {
            try
            {
                var db = new DatabaseContext();
                
                if (command == BaseHelper.PageAction.Add.ToString())
                {
                    db.EmployeeContracts.Add(model.Type);
                    if (model.Type.IsCurrent)
                    { db = SetOtherContractsToNotCurrent(db, model.Type.EmployeeCode, model.Type.ID); }
                    db.SaveChanges();
                }
                else if (command == BaseHelper.PageAction.Edit.ToString())
                {
                    if (model.Type.IsCurrent)
                    { db = SetOtherContractsToNotCurrent(db, model.Type.EmployeeCode, model.Type.ID);  }
                    db.Entry(model.Type).State = EntityState.Modified;
                    db.SaveChanges();
                }
                else
                {
                    // cancelled
                }
                
                db.Dispose();

                return RedirectToAction(BaseHelper.Page.EmployeeContracts.ToString(),
                    new { employeeCode = model.Type.EmployeeCode });
            }
            catch (Exception ex)
            {
                return Error(ex);
            }
        }

        public ActionResult SetContractAsCurrent(string employeeCode, int? id)
        {
            try
            {
                var db = new DatabaseContext();

                var contract = db.EmployeeContracts.Where(w => w.ID == id).SingleOrDefault<EmployeeContract>();
                contract.IsCurrent = true;
                db = SetOtherContractsToNotCurrent(db, employeeCode, id.GetValueOrDefault());

                db.Entry(contract).State = EntityState.Modified;
                db.SaveChanges();

                return RedirectToAction(BaseHelper.Page.EmployeeContracts.ToString(),
                    new { employeeCode = employeeCode });
            }
            catch (Exception ex)
            {
                return Error(ex);
            }
        }

        private DatabaseContext SetOtherContractsToNotCurrent(DatabaseContext db, string employeeCode, int id)
        {
            var list = db.EmployeeContracts.Where(w => w.EmployeeCode == employeeCode && w.ID != id);

            foreach (var item in list)
            {
                item.IsCurrent = false;
            }

            return db;
        }

        #endregion

    }
}
